package com.lc.learn.netty.client;

import cn.hutool.core.exceptions.ExceptionUtil;
import com.alibaba.fastjson2.util.DateUtils;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelId;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @description: 客户端处理接收器
 * @author: LChuang
 * @date: 2023/10/28 14:33
 */
@Slf4j
public class NettyClientHandler extends ChannelInboundHandlerAdapter {

    /**
     * 计算有多少客户端接入，第一个string为客户端ip
     */
    private static final ConcurrentHashMap<ChannelId, ChannelHandlerContext> CLIENT_MAP = new ConcurrentHashMap<>();


    /**
     * 客户端连接服务端触发
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        CLIENT_MAP.put(ctx.channel().id(), ctx);
        log.info("客户端【{}】成功连接服务端。", ctx.channel().id());
    }


    /**
     * 客户端断开服务端触发
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        ctx.close();
        log.info("客户端【{}】断开服务端连接。", ctx.channel().id());
    }


    /**
     * 客户端接收服务端回响数据
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        log.info("客户端【{}】接收 服务端 回写数据：{}", ctx.channel().id(), msg);
    }


    /**
     * 客户端发生异常时触发
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.info("客户端发生异常！连接中断。");
        log.error(ExceptionUtil.stacktraceToString(cause));
        ctx.close();
    }



    public void channelWrite(ChannelId channelId, String msg) {
        ChannelHandlerContext ctx = CLIENT_MAP.get(channelId);
        if (Objects.isNull(ctx)) {
            log.info("服务端管道【{}】已断开连接！", channelId);
            return;
        }
        //将客户端的信息直接返回写入ctx
        ctx.write(msg + " 时间：" + LocalDateTime.now());
        //刷新缓存区
        ctx.flush();
    }

}
